package com.tianpengtech.common.generator.app;

import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.template.Engine;
import com.tianpengtech.common.generator.model.CodeBean;
import com.tianpengtech.common.generator.model.TableInfo;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/*
    没事别动这里，重构也不行
 */
public class Generator {


    private static final String VIEW_PATH = File.separator + "front" + File.separator + "generator" +
            File.separator + "views" + File.separator;


    private static  String PAGE_OUTPUT_BASEPATH = null;//PAGE基本路径
    private static  String ADMIN_CODEOUTPUT_BASEPATH= null ;//Admin管理后台基本路径
    private static  String MODEL_CODEOUTPUT_BASEPATH= null;//MODEL基本路径

    public static CodeBean build(String module, String modelName, String tableName, String tableRemark) {
        String dbName = "corperation";
        CodeBean bean = CodeBean.newOne(module);
        module = module.toLowerCase();
        bean.setDbName(dbName);
        bean.setModuleName(module);
        TableInfo tableInfo = TableInfo.buildTableInfo(dbName, modelName, tableName, tableRemark);
        tableInfo.setModelName(modelName);
        bean.setTable(tableInfo);
        return bean;
    }

    public static String generateExpressStr(String instanceName,String columnName){
        return String.format("#(%s.%s??'')",instanceName,columnName);
    }

    public static String generateJqueryIdStr(String str){
        return "#"+str;
    }

    public static String toLowCase(String str){
        return str.toLowerCase();
    }


    /*
        快捷生成所有的文件
     */
    public static void excute(Engine engine,String module, String modelName, String tableName, String tableRemark){


        Map<String, Object> param = getDbMeta(module, modelName, tableName, tableRemark);

        System.out.println("============【注意】：请自行配置数据库映射和路由============");
        System.out.println(String.format("路由配置地址(AdminRoutes)：add(\"/admin/%s\",%sAdminController.class, \"/admin/%s\");",
                toLowCase(modelName), modelName, toLowCase(modelName)));
        System.out.println(String.format("数据库映射地址(MyConfig)：arp.addMapping(%s.dao.tableName(),%s.class);", modelName, modelName));
        System.out.println("=============================================");

        createController(engine, modelName, ADMIN_CODEOUTPUT_BASEPATH, param);
        createModel(engine, modelName, MODEL_CODEOUTPUT_BASEPATH, param);
        createService(engine, modelName, ADMIN_CODEOUTPUT_BASEPATH, param);

        createListView(engine, modelName, PAGE_OUTPUT_BASEPATH, param);
        createAddView(engine, modelName, PAGE_OUTPUT_BASEPATH, param);
        createEditView(engine, modelName, PAGE_OUTPUT_BASEPATH, param);
        createFormView(engine, modelName, PAGE_OUTPUT_BASEPATH, param);


    }

    private static Map<String, Object> getDbMeta(String module, String modelName, String tableName, String tableRemark) {
        Map<String,Object> param = new HashMap<String, Object>();
        param.put("result", build(module, modelName, tableName, tableRemark));
        return param;
    }

    /*
        创建Controller
     */
    private static void createController(Engine engine, String modelName, String adminCodeOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        resultContent = parseFileContent(engine, VIEW_PATH,"controller.html", param);
        createFile(modelName, modelName + "AdminController.java", adminCodeOutPutBasePath, resultContent);
    }

    /*
        创建Model
     */
    private static void createModel(Engine engine, String modelName, String adminCodeOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        resultContent = parseFileContent(engine, VIEW_PATH,"model.html", param);
        createFile(modelName, modelName + ".java", adminCodeOutPutBasePath, resultContent);
    }

    /*
        创建Service实现类
     */
    private static void createService(Engine engine, String modelName, String adminCodeOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        resultContent = parseFileContent(engine, VIEW_PATH,"service-impl.html", param);
        createFile(modelName,modelName + "AdminServiceImpl.java", adminCodeOutPutBasePath, resultContent);
    }

    /*
        创建List列表页面
     */
    private static void createListView(Engine engine, String modelName, String pageOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        //创建列表文件代码文件
        resultContent = parseFileContent(engine, VIEW_PATH,"list-view.html", param);
        createFile(modelName,toLowCase(modelName+"-list.html"), pageOutPutBasePath, resultContent);
    }


    /*
        创建添加页面
     */
    private static void createAddView(Engine engine, String modelName, String pageOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        //创建列表文件代码文件
        resultContent = parseFileContent(engine, VIEW_PATH,"add-view.html", param);
        createFile(modelName,toLowCase("add-"+modelName+".html"), pageOutPutBasePath, resultContent);
    }

    /*
        创建编辑页面
     */
    private static void createEditView(Engine engine, String modelName, String pageOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        //创建列表文件代码文件
        resultContent = parseFileContent(engine, VIEW_PATH,"edit-view.html", param);
        createFile(modelName,toLowCase("edit-"+modelName+".html"), pageOutPutBasePath, resultContent);
    }

    /*
        创建表单页面
     */
    private static void createFormView(Engine engine, String modelName, String pageOutPutBasePath, Map<String, Object> param) {
        String resultContent;
        //创建列表文件代码文件
        resultContent = parseFileContent(engine, VIEW_PATH,"form-view.html", param);
        createFile(modelName,toLowCase(modelName+"-form.html"), pageOutPutBasePath, resultContent);
    }

    private static Engine engineConfig() {
        Engine engine;
        engine= Engine.create("code");
        String templateBasePath = PropKit.get("codeBaseTemplatePath");
        engine.setBaseTemplatePath(templateBasePath);//设置模板起始位置

        //设置分享模板的地址
        String macroViewPage= File.separator+"admin"+ File.separator+"macro"+
                File.separator+"macro.html";

        engine.addSharedFunction(macroViewPage);
        engine.addSharedStaticMethod(Generator.class);
        return engine;
    }


    /*
        创建文件
     */
    public static void createFile(String modelName,String viewName, String outPutBasePath, String resultContent) {
        try {
            File file = new File(outPutBasePath+File.separator+toLowCase(modelName)+File.separator);
            if(!file.exists()){
                file.mkdirs();
            }
            FileOutputStream o=null;
            o = new FileOutputStream(file+File.separator+viewName);
            o.write(resultContent.getBytes("UTF-8"));
            o.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
        解析模板中的文件内容
     */
    private static String parseFileContent(Engine engine, String viewPath,String viewName, Map<String, Object> param) {
        String resultContent;
        resultContent= engine.getTemplate(viewPath+viewName).renderToString(param);
        resultContent = resultContent.replace("^","");
        return resultContent;
    }

    /*
        启动数据库信息
     */
    private static void init() {
        PropKit.use("a_little_config.txt");
        DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("jdbcUrl"),
                PropKit.get("user"), PropKit.get("password").trim());

        String pageOutPutBasePath = PropKit.get("pageOutPutBasePath");
        String adminCodeOutPutBasePath = PropKit.get("adminCodeOutPutBasePath");
        String modelCodeOutPutBasePath = PropKit.get("modelCodeOutPutBasePath");

        PAGE_OUTPUT_BASEPATH = pageOutPutBasePath;
        ADMIN_CODEOUTPUT_BASEPATH = adminCodeOutPutBasePath;
        MODEL_CODEOUTPUT_BASEPATH = modelCodeOutPutBasePath;
        ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
        druidPlugin.start();
        arp.start();
    }

    public static void main(String[] args) {

        //请在a_little_config.txt中设置对应的路径（详情见配置文件）
        init();
        Engine engine = engineConfig();
//        Generator.excute(engine,".course", "Course", "dn_course", "课程表");
//        Generator.excute(engine,".role", "Role", "dn_role", "系统用户角色表信息");
//        Generator.excute(engine,".permission", "Permission", "dn_permission", "系统用户角色操作表信息");
//        Generator.excute(engine,".dictionary", "Dictionary", "dn_dictionary", "系统数据字典表");
//        Generator.excute(engine,".course", "Course", "dn_course", "学习课程表");

        String modelName = "Course";
        String packageName = ".course";
        String tableName =  "dn_course";
        String tableRemark = "课程表";

        Map<String,Object> param = getDbMeta(packageName,modelName,tableName,tableRemark);
        Generator.createModel(engine,modelName,MODEL_CODEOUTPUT_BASEPATH,param);
    }
}
